package com.attendance.service;

import com.attendance.annotation.Supplement;
import com.attendance.annotation.type.OperationType;
import com.attendance.mapper.MenuMapper;
import com.attendance.pojo.Menu;
import com.attendance.security.user.pojo.UserInfo;
import com.attendance.security.user.service.UserService;
import com.attendance.spring.SpringSecurityUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜单服务
 *
 * @author 今朝
 * @date 2021/03/14
 */
@Service
public class MenuServiceImpl {

    @Autowired
    MenuMapper menuMapper;
    @Autowired
    UserService userService;

    public List<Menu> getList() {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("idx");
        return menuMapper.selectList(queryWrapper);
    }

    public Boolean delete(Long id) throws Exception {
        Menu menuByParentId = menuMapper.findMenuTreeById(id);
        if (menuByParentId.getChildren().size() != 0) {
            throw new Exception("不能删除非根节点");
        }
        return menuMapper.deleteById(id) != 0;
    }

    public Menu selectById(Long id) {
        return menuMapper.selectById(id);
    }

    public Page<Menu> getListPage(Integer pageNum, Integer limit) {
        Page<Menu> page = new Page<>(pageNum, limit);
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("idx");
        menuMapper.selectPage(page, queryWrapper);
        return page;
    }

    public Page<Menu> getListPage(Integer pageNum, Integer limit, String title) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("title", title);
        queryWrapper.orderByAsc("idx");
        Page<Menu> page = new Page<>(pageNum, limit);
        menuMapper.selectPage(page, queryWrapper);
        return page;
    }

    @Supplement(type = OperationType.UPDATE)
    public Boolean updateById(Menu menu) {
        return menuMapper.updateById(menu) != 0;
    }

    @Supplement(type = OperationType.PUT)
    public Boolean addMenu(Menu menu) {
        return menuMapper.insert(menu) != 0;
    }

    public List<Menu> getMenus() {
        List<Menu> menuTreeRoots = new ArrayList<>();
        List<Long> menusIds = getMenusIdByUser();

        for (Menu menu : menuMapper.findMenuTreeRoots()) {
            if (menusIds.contains(menu.getId())) {
                menuTreeRoots.add(menu);
                traverseMenuTree(menu, menusIds);
            }
        }
        return menuTreeRoots;
    }

    public List<Long> getMenusIdByUser() {
        UserInfo userInfo = userService.selectByName(SpringSecurityUtils.getUserName());
        return menuMapper.findMenusByUserId(userInfo.getUserId());
    }

    public void traverseMenuTree(Menu menu, List<Long> menusIds) {
        if (menu.getChildren() != null) {
            List<Menu> menus = new ArrayList<>();
            for (Menu child : menu.getChildren()) {
                if (menusIds.contains(child.getId())) {
                    menus.add(child);
                    traverseMenuTree(child, menusIds);
                }
            }
            menu.setChildren(menus);
        }
    }

    public List<String> getMenusTitleByIds(List<Long> ids) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("idx");
        queryWrapper.in("id", ids);
        List<Menu> menus = menuMapper.selectList(queryWrapper);
        return menus.stream().map(Menu :: getTitle).collect(Collectors.toList());
    }

}
